<?php
	
	namespace Aspic\Cache;
	
	use Aspic as A;
	
	class RawFileCache extends AbstractFileCache {
		
		protected $_fileHeaderSeparator;

		/**
		 * 
		 * @param type $cacheDir
		 * @param type $performanceMode When true, cache data for a unique key 
		 * will only be retrieve one time and save in memory for further demands.
		 */
		public function __construct($cacheDir, $performanceMode = true) {
			parent::__construct($cacheDir, $performanceMode);
			
			$this->opt('fileHeaderSeparator', '#');
		}
		
		/**
		 * Clean all cache data (STILL VALID OR NOT) or only given key(s)
		 * @param array|string $keys Key(s) to clean
		 * @return type 
		 */
		public function clean($keys = array()) {
			if (is_string($keys)) {
			   $keys = array($keys);
			}

			$fg = new File\FilesGlob();
			$fg->setMatchType(File\FilesGlob::MATCH_TYPE_INC_EXTS, array($this->opt('cacheFilesExtension')));

			$files = $fg->find($this->opt('cacheDir'));

			if(count($files)) {
				$keysFilenames = array_map(function($key) {
					return $this->getKeyFileName($key);
				}, $keys);
			
				foreach($files as $file) {
					if (count($keys) == 0 OR in_array($file, $keysFilenames)) {
						unlink($this->opt('cacheDir').'/'.$file);
					}
				}
			}
		   
		}
		
		/**
		 * @param type $key
		 * @param type $data
		 * @param integer|string $expiresData A delay in second by which cache will be unvalided or 
		 * a file path for which filemtime() functions will determine if cache is still valid (when given file 
		 * is more recent than cache file)
		 * @param mixed $additionnalInfos Can be used to store additionnal informations about the cache 
		 * if needed by the child class. This will be serialized and then stored with the header
		 * @return null
		 */
		public function cache($key, $data, $expiresData = 86400) {
			$fp = $this->getCacheFilePath($key);

			$header = $expiresData;

			$toStore = $header.$this->opt('fileHeaderSeparator').$data;
			
			$this->setMemCache($key, $data, $expiresData);

			return File\File::putContents($fp, $toStore);
		}
		
		/**
		 * This method must be call from child classes that's why it is protected because $data should 
		 * be tampered (making a string with it in child class) before calling this one.
		 * @param type $key
		 * @param type $performanceMode
		 * @return null
		 */
		public function getCache($key, $performanceMode = null) {
			$performanceMode = (is_null($performanceMode))?$this->opt('performanceMode'):$performanceMode;
			
			if ($performanceMode AND isset($this->memCache[$key])) {
				return $this->getMemCache($key);
			}
			else {
				$fp = $this->getCacheFilePath($key);

				if (is_file($fp)) {
					$fileDataRaw = File\File::getContents($fp);

					$headerSepPos = strpos($fileDataRaw, $this->opt('fileHeaderSeparator'));
					$header = substr($fileDataRaw, 0, $headerSepPos);

					$expiresData = $header;

					$data = substr($fileDataRaw, $headerSepPos + 1);

					$ret = array(
						'expiresData' => $expiresData, 
						'data' => $data,
					);

					return $ret;
				}
				else {
					return null;
				}
			
			}
		}
			   
   }
